import { StorageService } from ".";
import {
    HTTP_STATUS_CODE_MAPPING,
    HTTP_HEADERS_CONTENT_TYPE,
} from "../config/http";
import { EStorage } from "../enums/storage.enum";
import { convertValues } from '../utils'


/** http网络请求参数 */
export interface IRequestProps {
    url: string;
    data?: string | AnyObject | ArrayBuffer | undefined;
    header?: Record<string, any>;
    method?: UniNamespace.RequestOptions["method"];
    timeout?: number;
}

// 响应拦截
const handlerResponese = (result: UniApp.RequestSuccessCallbackResult) => {
    let responseType = false;
    const { statusCode, data, header } = result;
    // 响应成功
    if (statusCode === 200 || statusCode === 201) {
        responseType = true;
    }
    // 响应异常
    else {
        const responseData = data as AnyObject | string;
        handlerErrorResponse(statusCode, typeof responseData === 'string' ? responseData : responseData.msg)
    }
    return {
        responseType,
        data
    }
}

// 响应异常处理
const handlerErrorResponse = (statusCode: number, errorMsg?: string) => {
    (errorMsg) && (uni.showToast({
        icon: 'error',
        title: errorMsg
    }))
    switch (statusCode) {
        case 400:
            break;
        case 401:
            break;
        default:
            break;
    }
}

const request: (option: IRequestProps) => Promise<any> = ({ url, data = {}, header = {}, method = 'GET', timeout = 10000 }) => {
    return new Promise((resolve, reject) => {
        const options = { url, method, data, header, timeout };
        uni.request({
            ...options,
            success(result) {
                const { responseType, data } = handlerResponese(result);
                if (responseType) {
                    resolve(data)
                } else {
                    reject(false)
                }
            },
            fail() { reject(false) }
        })
    })
}
uni.addInterceptor('request', {
    invoke(args: UniApp.RequestOptions) {
        const _header = {
            ...args.header,
            ...HTTP_HEADERS_CONTENT_TYPE.JSON.headers
        }
        const token = StorageService.getSync(EStorage.ACCESS_TOKEN).value;
        if (token) {
            Object.assign(_header, { token })
        }
        args.header = { ..._header }
        args.data = convertValues(args.data as AnyObject)
    }
})

export default {
    get(url: string, data: AnyObject = {}, header: AnyObject = {}) {
        return request({ url, method: 'GET', data, header })
    },
    post(url: string, data: AnyObject = {}, header: AnyObject = {}) {
        return request({ url, method: 'POST', data, header })
    }
}